{
  Copyright 2012 Sergey Ostanin

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
}

unit CommonModifiers;

interface

uses
  Classes, SysUtils, TestCore, MiscUtils, Modifiers;

type
  TSetEvaluationModelModifier = class(TModifier)
  private
    FLaxEvaluation: Boolean;
    FQuestionClasses: TQuestionClassList;
  public
    constructor Create; override;
    destructor Destroy; override;
    class function GetTitle: String; override;
    procedure Apply(var Question: TQuestion; Alterants: TAlterantList); override;
    procedure Assign(Source: TModifier); override;

    property LaxEvaluation: Boolean read FLaxEvaluation write FLaxEvaluation;
    property QuestionClasses: TQuestionClassList read FQuestionClasses;
  end;

  TSetEvaluationModelAlterant = class(TAlterant)
  private
    FLaxEvaluation: Boolean;
  public
    procedure Apply(var Question: TQuestion); override;

    property LaxEvaluation: Boolean read FLaxEvaluation write FLaxEvaluation;
  end;

  TSetWeightModifier = class(TModifier)
  private
    FNewWeight: Integer;
    procedure SetNewWeight(Value: Integer);
  public
    constructor Create; override;
    class function GetTitle: String; override;
    class function IsLegacy: Boolean; override;
    procedure Apply(var Question: TQuestion; Alterants: TAlterantList); override;
    procedure Assign(Source: TModifier); override;

    property NewWeight: Integer read FNewWeight write SetNewWeight;
  end;

  TSetWeightAlterant = class(TAlterant)
  private
    FNewWeight: Integer;
    procedure SetNewWeight(Value: Integer);
  public
    constructor Create; override;
    procedure Apply(var Question: TQuestion); override;

    property NewWeight: Integer read FNewWeight write SetNewWeight;
  end;

implementation

resourcestring
  SSetEvaluationModel = 'Set Scoring Mode';
  SSetWeight = 'Set Question Weight';

{ TSetEvaluationModelModifier }

procedure TSetEvaluationModelModifier.Apply(var Question: TQuestion;
  Alterants: TAlterantList);
var
  Alterant: TSetEvaluationModelAlterant;
begin
  if (Question.LaxEvaluation <> FLaxEvaluation)
    and ((FQuestionClasses.Count = 0)
    or (FQuestionClasses.IndexOf(TQuestionClass(Question.ClassType)) <> -1)) then
  begin
    Alterant := TSetEvaluationModelAlterant.Create;
    Alterants.Add(Alterant);

    Alterant.LaxEvaluation := FLaxEvaluation;
    Alterant.Apply(Question);
  end;
end;

procedure TSetEvaluationModelModifier.Assign(Source: TModifier);
var
  m: TSetEvaluationModelModifier;
begin
  inherited;
  m := Source as TSetEvaluationModelModifier;
  FLaxEvaluation := m.FLaxEvaluation;
  FQuestionClasses.Assign(m.FQuestionClasses);
end;

constructor TSetEvaluationModelModifier.Create;
begin
  inherited;
  FLaxEvaluation := TRUE;
  FQuestionClasses := TQuestionClassList.Create;
end;

destructor TSetEvaluationModelModifier.Destroy;
begin
  FreeAndNil(FQuestionClasses);
  inherited;
end;

class function TSetEvaluationModelModifier.GetTitle: String;
begin
  Result := SSetEvaluationModel;
end;

{ TSetEvaluationModelAlterant }

procedure TSetEvaluationModelAlterant.Apply(var Question: TQuestion);
begin
  Question.LaxEvaluation := FLaxEvaluation;
end;

{ TSetWeightModifier }

procedure TSetWeightModifier.Apply(var Question: TQuestion; Alterants: TAlterantList);
var
  Alterant: TSetWeightAlterant;
begin
  if Question.Weight <> FNewWeight then
  begin
    Alterant := TSetWeightAlterant.Create;
    Alterants.Add(Alterant);

    Alterant.NewWeight := FNewWeight;
    Alterant.Apply(Question);
  end;
end;

procedure TSetWeightModifier.Assign(Source: TModifier);
begin
  inherited;
  FNewWeight := (Source as TSetWeightModifier).FNewWeight;
end;

constructor TSetWeightModifier.Create;
begin
  inherited;
  FNewWeight := 1;
end;

class function TSetWeightModifier.GetTitle: String;
begin
  Result := SSetWeight;
end;

class function TSetWeightModifier.IsLegacy: Boolean;
begin
  Result := TRUE;
end;

procedure TSetWeightModifier.SetNewWeight(Value: Integer);
begin
  Assert( Value >= 1 );
  FNewWeight := Value;
end;

{ TSetWeightAlterant }

procedure TSetWeightAlterant.Apply(var Question: TQuestion);
begin
  Question.Weight := FNewWeight;
end;

procedure TSetWeightAlterant.SetNewWeight(Value: Integer);
begin
  Assert( Value >= 1 );
  FNewWeight := Value;
end;

constructor TSetWeightAlterant.Create;
begin
  inherited;
  FNewWeight := 1;
end;

initialization

  ModifierRegistry.Add(TSetEvaluationModelModifier);
  ModifierRegistry.Add(TSetWeightModifier);

end.

